# This file is part of GPropertyGrid project. 
# The COPYRIGHT file at the top level of this repository 
# contains the full copyright notices and license terms.

from gi.repository import Gtk

class PropertyGridProperty(Gtk.Paned):    
    def __init__(self, name, value_widget, 
                id=None,
                default=None,
                description=None,
                force_value=False):
                
        super(PropertyGridProperty, 
                self).__init__(orientation=Gtk.Orientation.HORIZONTAL)

        self._group=None # PropertyGridGroup
        self.name = name
        self.id=id
        self.default = default
        self.value = None
        self.description = description
        
        self._curr_width=-1
        self._curr_position=-1
        self._has_focus=False
        self._has_changed=False
        self._read_only=False
        
        if force_value:
            self.value=self.default
        
        self.box_0=Gtk.Box()
        self.box_1=Gtk.Box()
        self.event_box_0=None
        self.event_box_1=None
        self.cell_0=None
        self.cell_1=None
                
        self.pack1(self.get_cell(0), True, True)
        self.pack2(self.get_cell(1), True, True)               
        
        self.connect("draw", self.on_draw)
        
        self.cell_0.set_text(name)

        self.value_widget = value_widget
        
    @property
    def has_focus(self):
        return self._has_focus

    @property
    def has_changed(self):
        return self._has_changed

    @has_changed.setter
    def has_changed(self, value):
        self._has_changed = value
        self._group._grid._property_changed(self)

    def get_cell(self, cell_index):
        if cell_index==0:
            self.cell_0 = Gtk.Label(xalign=0)
            self.event_box_0 = Gtk.EventBox()            
            cell = self.cell_0
            ebox=self.event_box_0
            box = self.box_0
        else:
            self.cell_1 = Gtk.Label(xalign=0)
            self.event_box_1 = Gtk.EventBox()
            cell = self.cell_1
            ebox=self.event_box_1
            box = self.box_1
        #cell.set_name("cell_{0}".format(cell_index))
        cell.set_name("cell")
        ebox.add(cell)
        
        ebox.connect("enter-notify-event", self.on_mouse_notify, 
                    {"index":cell_index,
                     "type":"in"})
        ebox.connect("leave-notify-event", self.on_mouse_notify,
                    {"index":cell_index,
                     "type":"out"})
                     
        ebox.connect("button-press-event", self.on_cell_click,
                                {"index":cell_index})

        box.pack_start(ebox, True, True, 0)
        return box 
        
    def on_mouse_notify(self, box, event_type, data):
        self.change_cell_color(0, data["type"])
        self.change_cell_color(1, data["type"])
    
    def change_cell_color(self, cell_index, data_type):
        if cell_index==0:
            cell = self.cell_0
        else:
            cell = self.cell_1
        ctx = cell.get_style_context()
        if data_type=="in":
            ctx.add_class("cell_in")
        else:
            ctx.remove_class("cell_in")

    def on_draw(self, wg, data):
        if self.get_allocated_width() != self._curr_width:
            position = int(self.get_allocated_width() / 3)
            self.set_curr_position(position)
            self._curr_width = self.get_allocated_width()
        else:
            for p in self._group.properties:
                p.set_curr_position(self.get_position())
            
    def set_curr_position(self, position):
        if self._curr_position != position:
            self.set_position(position)
        self._curr_position = position
        
    def on_cell_click(self, box, event_type, data):
        self.show_hide_value_widget()
        
    def show_hide_value_widget(self):
        if self._read_only:
            self.on_enter() # force on_leave() on all properties
            return
        curr_wg = self.box_1.get_children()[0]
        if self._has_focus:
            new_wg = self.event_box_1
        else:
            new_wg = self.value_widget
        
        self.box_1.remove(curr_wg)
        self.box_1.pack_start(new_wg, True, True, 0)
        self.box_1.show_all()
        if not self._has_focus:
            new_wg.grab_focus()
            self.on_enter()
        self._has_focus = not self._has_focus

    def set_value_text(self, text):
        if not text:
            self.cell_1.set_text("[No value]")
        else:
            self.cell_1.set_text(text)
            
    def set_read_only(self, value):
        self._read_only=value
        self.cell_1.set_selectable(value)

    def get_value(self):
        return self.value
    
    def on_enter(self, data=None):
        self._group.grid._on_enter_widget(self.id)
        
    def on_leave(self, data=None):
        self.value_widget.set_sensitive(False)
        raise NotImplementedError("on_leave() function must be defined " \
                    "by the 'PropertyGridProperty' derived class")

    def on_change(self, data=None):
        if not self._has_focus:
            return False
        return True
 
